#include <avr/io.h>

struct ring_buffer
{
	volatile uint8_t write_offset;
	volatile uint8_t read_offset;
	uint8_t size;
	uint8_t *buffer;
};

static inline struct ring_buffer ring_buffer_init(uint8_t *buffer, uint8_t size)
{
	struct ring_buffer ring;
	ring.write_offset = 0;
	ring.read_offset = 0;
	ring.size = size;
	ring.buffer = buffer;
	return ring;
}

struct ring_buffer ring_buffer_transmit;
struct ring_buffer ring_buffer_receive;

static inline uint8_t get_next(uint8_t cur_offset, uint8_t max_offset)
{
	if (cur_offset == max_offset)
	{
		return 0;
	}
	else
	{
		return cur_offset + 1;
	}
}

static inline uint8_t ring_buffer_get_next_write(const struct ring_buffer *ring)
{
	return get_next(ring->write_offset, ring->size);
}

static inline uint8_t ring_buffer_get_next_read(const struct ring_buffer *ring)
{
	return get_next(ring->read_offset, ring->size);
}

static inline uint8_t ring_buffer_is_full(const struct ring_buffer *ring)
{
	return (ring->read_offset == ring_buffer_get_next_write(ring));
}

uint8_t ring_buffer_is_empty(const struct ring_buffer *ring)
{
	return (ring->read_offset == ring->write_offset);
}

uint8_t ring_buffer_get(struct ring_buffer *ring)
{
	uint8_t data = ring->buffer[ring->read_offset];
	ring->read_offset = ring_buffer_get_next_read(ring);
	return data;
}

void ring_buffer_put(struct ring_buffer *ring, uint8_t data)
{
	ring->buffer[ring->write_offset] = data;
	ring->write_offset = ring_buffer_get_next_write(ring);
}

static inline uint8_t uart_char_waiting(void)
{
	return !ring_buffer_is_empty(&ring_buffer_receive);
}





